var http_request = null;

var EstesPark = {
units:"f",
keyword:"Currently ",
beginIndex:10,
endIndex:20,
forecastURL:"http://www.wunderground.com/cgi-bin/findweather/getForecast?query=estes park, co&wuSelect=WEATHER"
}

var Boulder = {
units:"f",
keyword:"<th>Temperature</th>",
beginIndex:62,
endIndex:70,
forecastURL:"http://www.wunderground.com/cgi-bin/findweather/getForecast?query=boulder, co&wuSelect=WEATHER"
}

var Calonge = {
units:"c",
keyword:"dadesactuals\">",
beginIndex:14,
endIndex:20,
forecastURL:"http://www.accuweather.com/world-index-forecast.asp?partner=accuweather&traveler=0&loccode=EUR|ES|SP008|CALONGE"
}

var Tossa = {
units:"c",
keyword:"dadesactuals\">",
beginIndex:14,
endIndex:20,
forecastURL:"http://www.accuweather.com/world-index-forecast.asp?partner=accuweather&locCode=EUR|ES|SP008|Tossa%20De%20Mar|&u=1"
}

var EmeraldHills = {
units:"f",
keyword:"Outside Temperature: ",
beginIndex:21,
endIndex:24,
forecastURL:"http://www.wunderground.com/cgi-bin/findweather/getForecast?query=emerald hills, ca&wuSelect=WEATHER"
}    



// ----------------------------------------------------------------------------
function weather() {
  // weather preference class
  this.w_prefs = new weather_prefs();
  this.w_prefs.initPrefs();
  this.curObj = null;

  // add pref observers
  this.PrefChangeObserver = {
    observe: function(aSubject, aTopic, aData)
    {
      gWeather.prefChanged(aData);
    }
  };

  this.w_prefs.addObserver("weather", this.PrefChangeObserver);

  // get XPCOM manager service
//  var obs = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);

}


// ------------------------------------------------------------------------------
weather.prototype.prefChanged = function(aPrefName) {
  switch(aPrefName){
    case gWeather.w_prefs.PREF_UNITS:
      gWeather.updateTemp(false);
      break;
    case gWeather.w_prefs.PREF_STATION:
      gWeather.setLocation(gWeather.getLocation());
      gWeather.updateTemp(false);
      break;
  }
}


// ----------------------------------------------------------------------------
weather.prototype.openForecast = function(event) {
  // right click calls this on windows
  if(event && (event.button == 2)) return;

  if(event && (event.button == 1)) {
    // middle click
    this.visitURL(this.getStationUrl());        
  } else if (event && (event.button == 0)) {
    // left click
    this.visitURL(this.getForecastUrl());    
  }
}


// ----------------------------------------------------------------------------  
weather.prototype.visitLocation = function() {
  this.visitURL(this.getStationUrl());
}


// ----------------------------------------------------------------------------  
/**
 * Opens the given URL into the browser, depending on the preference value:
 * 0 - current tab
 * 1 - new tab
 * 2 - new window 
 * 3 - new unfocused tab
 *
 * @param aOverride - force a certain load method
 */
weather.prototype.visitURL = function(url, override) {

  var linkLoadLocation = override ? override : this.getLinkLoadLocation();
  
  if(linkLoadLocation == 2) {
    window.open(url);
  } else if ((linkLoadLocation == 1) || (linkLoadLocation == 3)) {
    var myTab = getBrowser().addTab(url, null, null);

    if(linkLoadLocation == 1)
      getBrowser().selectedTab = myTab;
  } else {
    getBrowser().loadURI(url);
  }
}
  

// ----------------------------------------------------------------------------  
weather.prototype.parsePage = function() {
  this.weather_bar = document.getElementById("weather_bar");

  if(gWeather.curObj == null)
  {
    alert("the gWeather.curObj is null");
  }
  if(http_request.readyState == 4) {
    var tempf    = 0;
    var response = http_request.responseText;
    var index    = response.indexOf(gWeather.curObj.keyword);
    var temp     = response.substring(index+gWeather.curObj.beginIndex,
                                      index+gWeather.curObj.endIndex);

    // get temperature data from site    
    if(temp.indexOf(".") == 1) {
      tempf = temp.substring(2,3);
      temp  = temp.substring(0,1);   
    }  else if(temp.indexOf(".") == 2) {
      tempf = temp.substring(3,4);   
      temp  = temp.substring(0,2);
    }  else if(temp.indexOf(".") == 3) {
      tempf = temp.substring(4,5);
      temp  = temp.substring(0,3);   
    }

    // put into one number
    degrees = temp + "." + tempf;
    
    var units = gWeather.getUnits();
    // convert to the correct units
    if(units != gWeather.curObj.units) {
      if(units == "c" && gWeather.curObj.units == "f") {
        degrees = gWeather.convertF2C(degrees);
      } else if(units == "f" && gWeather.curObj.units == "c") {
        degrees = gWeather.convertC2F(degrees);
      }
    } 

    // get an integer for the number
    fixed = parseInt(degrees);

    var icon = "chrome://weather/skin/" + units
               + "/" + fixed + ".ico";

    this.weather_bar.src = icon;
    this.weather_bar.setAttribute("tooltiptext",
				  gWeather.getLocation() + ": "
                                  + degrees + " degrees " + units);

    // try {
    //   var alertService = Components.classes["@mozilla.org/alerts-service;1"]
    //     .getService(Components.interfaces.nsIAlertsService);
    //   if (alertService && 0) {
    //     alertService.showAlertNotification(icon,
    //     				   "Firefox Weather",
    //     				   gWeather.getLocation() + ": " + temp
    //     				   + "." + tempf + " degrees",
    //     				   true,
    //     				   "",
    //     				   null);
    //   } else {

    //   }
    // } catch(e) {

    // }
    
  }
}


// ------------------------------------------------------------------------------
weather.prototype.convertF2C = function(f) {
  c = (5.0/9.0) * (f-32);
  return c.toFixed(1);
}


// ------------------------------------------------------------------------------
weather.prototype.convertC2F = function(c) {
  f = 1.8*c + 32.0;
  return f.toFixed(1);
}  
  

// ----------------------------------------------------------------------------
weather.prototype.displayForecast = function() {
  if(this.w_prefs.getBoolPref(this.w_prefs.PREF_QUICK_FORECAST))
    forecastWindow = window.openDialog("chrome://weather/content/forecast.xul",
				       "Forecast", "dependent, centerscreen");
}


// ----------------------------------------------------------------------------  
weather.prototype.updateTemp = function(setTimer) {
  http_request = new XMLHttpRequest();
  var location = this.getLocation();

  http_request.onload = this.parsePage;
  http_request.overrideMimeType('text/plain');
  http_request.open("GET", this.getStationUrl(), true);
  http_request.send(null);
  
  if(setTimer) {
    setTimeout("gWeather.updateTemp(true)", 300000); // 5 minutes
  }
}


// ----------------------------------------------------------------------------  
weather.prototype.getLocation = function() {
  return this.w_prefs.getCharPref(this.w_prefs.PREF_STATION);
}


// ----------------------------------------------------------------------------  
weather.prototype.getLinkLoadLocation = function() {
  return this.w_prefs.getIntPref(this.w_prefs.PREF_LOAD_LOCATION);
}


// ----------------------------------------------------------------------------  
weather.prototype.getForecastUrl = function() {
  return gWeather.curObj.forecastURL;
}

  
// ----------------------------------------------------------------------------  
weather.prototype.getUnits = function() {
  units = this.w_prefs.getIntPref(this.w_prefs.PREF_UNITS);
  if(units == 0) {
    return "f";
  } else {
    return "c";
  }
}    


// ----------------------------------------------------------------------------  
weather.prototype.getStationUrl = function() {
  var location = this.getLocation();

  if(location == "Boulder Foothills") {
    return "http://www.eol.ucar.edu/cgi-bin/weather.cgi?site=fl&period=5-minute&fields=tdry&fields=rh&fields=cpres0&fields=wspd&fields=wdir&fields=raina&units=english";
  } else if(location == "Boulder Table Mesa") {
    return "http://www.eol.ucar.edu/cgi-bin/weather.cgi?fields=tdry&fields=rh&fields=cpres0&fields=wspd&fields=wdir&fields=raina&site=ml&units=english&period=5-minute";    
  } else if(location == "Estes Park") {
    return "http://estesparkweather.net/index.php";
  } else if(location == "Calonge") {
    return "http://www.meteoclimatic.com/index/pg.0.fitxa.php?st=ESCAT1700000017251B";
  } else if(location == "Tossa de Mar") {
    return "http://www.meteoclimatic.com/perfil/ESCAT1700000017320A";    
  } else if(location == "Emerald Hills") {
    return "http://www.anegada.com/weather/details.htm";
  }
  return "";
}


// ----------------------------------------------------------------------------  
// Called when the user clicks the check box in the context menu of the 
// statusbar
weather.prototype.setLocation = function(location, quick) {
  this.estespark = document.
    getElementById("weather-context-menu-statusbar-item-estespark");
  this.boulderFoothills = document.
    getElementById("weather-context-menu-statusbar-item-boulder-foothills");
  this.boulderTableMesa = document.
    getElementById("weather-context-menu-statusbar-item-boulder-table-mesa");
  this.calonge = document.
    getElementById("weather-context-menu-statusbar-item-calonge");
  this.tossa = document.
    getElementById("weather-context-menu-statusbar-item-tossa");  
  this.emeraldhills = document.
    getElementById("weather-context-menu-statusbar-item-emeraldhills");    


// radio buttons would make sense instead of checkboxes,
// but eventually there will be the ability to add more than one station  
  if(location == "Estes Park") {
    this.estespark.setAttribute("checked", true);
    this.boulderFoothills.setAttribute("checked", false);
    this.boulderTableMesa.setAttribute("checked", false);
    this.calonge.setAttribute("checked", false);
    this.tossa.setAttribute("checked", false);        
    this.emeraldhills.setAttribute("checked", false);            
    this.curObj = EstesPark;
  } else if(location == "Boulder Foothills") {
    this.estespark.setAttribute("checked", false);
    this.boulderFoothills.setAttribute("checked", true);
    this.boulderTableMesa.setAttribute("checked", false);
    this.calonge.setAttribute("checked", false);
    this.tossa.setAttribute("checked", false);            
    this.emeraldhills.setAttribute("checked", false);            
    this.curObj = Boulder;
  } else if(location == "Boulder Table Mesa") {
    this.estespark.setAttribute("checked", false);
    this.boulderFoothills.setAttribute("checked", false);
    this.boulderTableMesa.setAttribute("checked", true);
    this.calonge.setAttribute("checked", false);
    this.tossa.setAttribute("checked", false);            
    this.emeraldhills.setAttribute("checked", false);            
    this.curObj = Boulder;    
  } else if(location == "Calonge") {
    this.estespark.setAttribute("checked", false);
    this.boulderFoothills.setAttribute("checked", false);
    this.boulderTableMesa.setAttribute("checked", false);
    this.calonge.setAttribute("checked", true);
    this.tossa.setAttribute("checked", false);            
    this.emeraldhills.setAttribute("checked", false);        
    this.curObj = Calonge;
  } else if(location == "Tossa de Mar") {
    this.estespark.setAttribute("checked", false);
    this.boulderFoothills.setAttribute("checked", false);
    this.boulderTableMesa.setAttribute("checked", false);
    this.calonge.setAttribute("checked", false);
    this.tossa.setAttribute("checked", true);    
    this.emeraldhills.setAttribute("checked", false);        
    this.curObj = Tossa;        
  } else if(location == "Emerald Hills") {
    this.estespark.setAttribute("checked", false);
    this.boulderFoothills.setAttribute("checked", false);
    this.boulderTableMesa.setAttribute("checked", false);
    this.calonge.setAttribute("checked", false);
    this.tossa.setAttribute("checked", false);            
    this.emeraldhills.setAttribute("checked", true);    
    this.curObj = EmeraldHills;    
  }  
  

  if(quick == null) {
    this.w_prefs.setCharPref(this.w_prefs.PREF_STATION, location);
    this.updateTemp(false);
  }
}


// ----------------------------------------------------------------------------  
weather.prototype.loadPrefWindow = function() {
  window.openDialog("chrome://weather/content/prefs.xul", 
                    "_blank", 
                    "centerscreen, chrome,resizable=no,dependent=yes")
}


// ----------------------------------------------------------------------------  
weather.prototype.onload = function() {
  gWeather.setLocation(gWeather.getLocation(), true);  
  gWeather.updateTemp(true);
}


// ----------------------------------------------------------------------------  
weather.prototype.unload = function() {
  // remove the observers
  if(gWeather.w_prefs) {
    gWeather.w_prefs.removeObserver("weather", gWeather.PrefChangeObserver);
  }

  // var obs = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  // obs.removeObserver(this, "weather-manager");
  // obs = null;

  // clear the object
  gWeather = null;
}  


  
var gWeather = new weather();
  
window.addEventListener("load", gWeather.onload, false);
window.addEventListener("unload", gWeather.unload, false);
